package lincen.javase.util.probability;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

import lincen.javase.util.array.ArrayUtil;

/**
 * 概率工具
 * @author 	林岑
 * @time	2012年3月23日 14:53:19
 */
/**
 * @author Administrator
 *
 */
public class ProbabilityUtil {
	
	private static Random r = new Random();
	
	/**
	 * 以一定几率发生某件事发生
	 * 前置条件:
	 * 	0 <= percent <= 1 
	 * 如果 percent >= 1, 那么事件就始终发生
	 * 如果 percent <= 0, 那么时间就从不发生
	 * @param percent 发生的几率
	 * @return true: 发生, false: 未发生
	 */
	public static boolean isHappen(float percent) {
		synchronized (r) {
			return percent > r.nextFloat();
		}
	}

	/**
	 * 传入概率序列 , 随机生成对应int数值(索引位置)
	 * 通过概率序列随机生成 0 - (length - 1) 这些整型数字, 
	 * 其各自的概率为is[0]  --- is[length - 1] 
	 * 
	 * 	例如:产生 3 的概率就是is[2]
	 * 
	 * @param is		概率序列
	 * @return			概率序列对应的整型值
	 */
	public static int getRandomInt ( int... is ) {
		synchronized (r) {
			int v = r.nextInt(ArrayUtil.sumOfSubArray(is, is.length));
			for (int i = 0; i < is.length; i++) {
				if(v < ArrayUtil.sumOfSubArray(is, i + 1)) {
					return i;
				}
			}
			return -1;
		}
	}
	
	/**
	 * 
	 * 传入权重序列 , 返回随机产生的权重索引位置
	 * 
	 * 
	 * 
	 * 比如传入[1000,12,456,34,67,89], 2
	 * 
	 * 那么返回[0,2]的可能性就最大...  其中0为1000的索引位置, 2为456的索引位置
	 * 
	 * 
	 * @param weights	权重序列
	 * @param returnSize	返回的数组的长度
	 * @return
	 */
	public static Set<Integer> randomByWeight(int returnSize, int... weights) {
		Set<Integer> s = new HashSet<Integer>();
		while(s.size() < returnSize) {
			s.add(getRandomInt(weights));
		}
		return s;
	}
	
	public static void main(String[] args) {
		for (int i = 0; i < 100000000; i++) {
			System.out.println("start");
			System.out.println(randomByWeight(5, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18));
		}
		System.out.println("end");
	}
}
